package composer.base;

import java.util.Vector;

import javax.microedition.media.control.MIDIControl;

public class NotesOffThread extends Thread {

	private Note[] notes;

	private byte[] channels;

	private long milisPerBeat;

	private MIDIControl midiControl;

	public NotesOffThread(Vector tracks, MIDIControl midiControl, int sbpm) {
		this.milisPerBeat = (1000 * 60) / sbpm;
		this.midiControl = midiControl;

		int numberOfNotes = 0;
		for (int i = 0; i < tracks.size(); i++) {
			numberOfNotes += ((Track) tracks.elementAt(i)).getNotes().size();
		}
		this.notes = new Note[numberOfNotes];
		this.channels = new byte[numberOfNotes];

		int counter = 0;
		for (int i = 0; i < tracks.size(); i++) {
			Track track = ((Track) tracks.elementAt(i));
			for (int j = 0; j < track.getNotes().size(); j++) {
				notes[counter] = (Note) track.getNotes().elementAt(j);
				channels[counter] = track.getChannel();
				counter++;
			}
		}

		for (int i = 0; i < this.notes.length; i++) {
			for (int j = i + 1; j < this.notes.length; j++) {
				int note1EndPosition = this.notes[i].getPosition() + this.notes[i].getDuration();
				int note2EndPosition = this.notes[j].getPosition() + this.notes[j].getDuration();
				if (note1EndPosition > note2EndPosition) {
					Note temp = this.notes[i];
					this.notes[i] = this.notes[j];
					this.notes[j] = temp;

					byte tmpChannel = this.channels[i];
					this.channels[i] = this.channels[j];
					this.channels[j] = tmpChannel;
				}
			}
		}
	}

	public void run() {
		System.out.println("running notes on thread.");
		long songStartTime = System.currentTimeMillis();
		int counter = 0;
		while (counter < this.notes.length) {
			long noteEndTime = (this.notes[counter].getPosition() + this.notes[counter].getDuration()) * this.milisPerBeat;
			long elapsed = System.currentTimeMillis() - songStartTime;
			try {
				Thread.sleep(noteEndTime - elapsed);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			midiControl.shortMidiEvent(
					0x80 | (int)this.channels[counter], 
					this.notes[counter].getTone(),
					this.notes[counter].getIntensity());
			counter = counter + 1;
		}
	}

}
